home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS18.ADF
/
Progs
/
defdisk
/
defdisk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-01-27
|
8KB
|
290 lines
/*
* DEFDISK.C
*
* A program to make a specified disk/directory the default system disk.
* It accomplishes this by resetting the DOS library structures to point
* to the new path. To use this program you will need to compile it as
* follows:
* 1> cc defdisk
* 1> ln defdisk.o -lc
*
* Real simple. I used AZTEC C v3.40a, but I think that 3.30c or later would
* also work. It should be possible to compile & build it under LATTICE as
* well, though I haven't tried. Once the program is built, put it on your
* Workbench boot disk somewhere, load up your ram: disk or hard disk and
*
* 1> defdisk dh0:
* or
* 1> defdisk dh0:bin
*
* Woila! the standard workbench assignments are now pointed at the hard
* disk. (SYS, C, L, DEVS, LIBS, FONTS) The advantage to me in using this
* is that I don't have to load the Amiga DOS assign program 6 times to
* point the system at the hard disk.
*
* Author: J. K. Levie
*
* Version 1.0 31-Mar-1987
*/
#include <stdio.h>
#include <functions.h>
#include <exec/types.h>
#include <exec/exec.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
extern void BtoCSTR(); /* forward ... */
extern void CtoBSTR(); /* ... references */
struct DevInfo
{
BPTR di_Next;
LONG di_Type;
APTR di_Task;
BPTR di_Lock;
BSTR di_Handler;
LONG di_StackSize;
LONG di_Priority;
LONG di_Startup;
BPTR di_SegList;
BPTR di_GlobVec;
BSTR di_Name;
};
struct DosLibrary *dosBase;
struct RootNode *root;
struct DosInfo *info;
struct DevInfo *dev_head, *dev_ele;
struct Lock *lock;
/*
* Define the logical to physical table.
*/
struct ASSIGNS
{
char *log_name; /* logical name to look for */
char *phy_name; /* physical name to assign */
short success; /* result 0=> failure, 1=> success */
};
struct ASSIGNS assigns[]=
{
"SYS", NULL, 0,
"C", "c", 0,
"DEVS", "devs", 0,
"LIBS", "libs", 0,
"L", "l", 0,
"S", "s", 0,
"FONTS", "fonts", 0,
NULL, NULL
};
main(argc, argv)
int argc;
char *argv[];
{
char *ptr, *path;
register int len, n;
/*
* See if we can get a lock on the new C directory, if we can't
* we won't even attempt to do the assigns.
*/
path=argv[1];
if(argc!=2 || *path=='?') /* correct arg cnt? useage? */
{
printf("Usage: defdisk dev:[dir.../dir]\n");
exit(20);
}
/*
* Now we are ready to fill in the logical name table. Handle the
* Sys logical first since it will not have anything appended. Then
* see if we will need to append a path separator to the user
* specified path. We stop appending when we see the "T" logical.
*/
assigns[0].phy_name=path; /* Sys is special case */
len=1+strlen(path); /* find length of physical name */
if(path[strlen(path)-1]!=':') /* path specify the root of volume? */
{
len++; /* room for path separator */
ptr=AllocMem((long)(len+1), MEMF_PUBLIC);
strcpy(ptr, path); /* put user specified path in ... */
strcat(ptr, "/"); /* ... and path separator */
path=ptr; /* point to new path */
}
/*
* Now fill in the rest of the table. Allocate memory for the
* complete physical name and the directory specified in the table
* entry. Then concatenate the path and the directory and set up
* the new pointer.
*/
for(n=1; assigns[n].log_name[0]!=NULL; n++)
{
ptr=AllocMem((long)(len+strlen(assigns[n].log_name)), MEMF_PUBLIC);
strcpy(ptr, path);
strcat(ptr, assigns[n].phy_name);
assigns[n].phy_name=ptr;
}
/*
* Convert the logical names to B strings.
*/
for(n=0; assigns[n].log_name!=NULL; n++) CtoBSTR(assigns[n].log_name);
/*
* Now for a little paranoia. I don't want to point the system
* somewhere that doesn't contain a C directory.
*/
lock=Lock(assigns[1].phy_name, SHARED_LOCK);
if(lock==NULL) /* are we sane? */
{
/*
* NO! Makes no sense to set the system volume to something that
* doesn't contain a c directory.
*/
printf("defdisk-F-%s does not contain a C directory\n",
assigns[1].phy_name);
exit(20);
}
UnLock(lock); /* Okay unlock the c directory */
/*
* Now open the resources we will need.
*/
dosBase=(struct DosLibrary *)OpenLibrary(DOSNAME);
root=(struct RootNode *)dosBase->dl_Root;
info=(struct DosInfo *)BADDR(root->rn_Info);
dev_head=(struct DevInfo *)BADDR(info->di_DevInfo);
Forbid(); /* only us & nobody else */
/*
* Walk the DevInfo list looking for the locigal names to change. For
* each entry in the list we can check each of the entries in the
* logical name table. As we find them reset each logical to point
* to the new system volume.
*/
for(dev_ele=dev_head; dev_ele->di_Next;
dev_ele=(struct DevInfo *)BADDR(dev_ele->di_Next))
{
/*
* Check against each of the logical names in the table.
*/
for(n=0; assigns[n].log_name!=NULL; n++)
{
/*
* See if this one matches.
*/
if(Bstrcmp(BADDR(dev_ele->di_Name), assigns[n].log_name))
{
/*
* Name matches, is it the correct type?
*/
if(dev_ele->di_Type!=DLT_DIRECTORY)
{
/*
* No put logical name back to a C string and error out.
*/
BtoCSTR(assigns[n].log_name);
printf("defdisk-F-cannot reassign %s\n", assigns[n].log_name);
goto done;
}
/*
* Okay get a lock on the physical name for this logical.
*/
lock=Lock(assigns[n].phy_name, SHARED_LOCK);
if(!lock)
{
/*
* Whoops, failed somehow, tell the world about it.
*/
printf("defdisk-F-cannot get a lock on %s\n", assigns[n].phy_name);
goto done;
}
/*
* Time to clean up the old logical and point it to our
* physical name.
*/
UnLock(dev_ele->di_Lock);
dev_ele->di_Lock=(BPTR)lock;
dev_ele->di_Task=(APTR)(DeviceProc(assigns[n].phy_name));
assigns[n].success=1; /* flag that we did this one */
}
}
}
done:
Permit(); /* release the system */
CloseLibrary(dosBase); /* clean up */
/*
* Now check to see that all of the assignments were made.
*/
for(n=0; assigns[n].log_name!=NULL; n++)
{
if(assigns[n].success!=1) printf("defdisk-F-assignments failed\n");
}
}
/*
* Bstrcmp(a, b)
*
* Compare two btrings for equality, case insensitive.
*/
Bstrcmp(a, b)
char *a, *b;
{
int len=(int)*a; /* first char of B string is length */
for(len++; len!=0; len--) /* compare at most all */
{
if((*a&~0x20)!=(*b&~0x20)) return(0); /* quit if not equal */
a++; /* point both ... */
b++; /* ... at next character */
}
return(1); /* they matched */
}
/*
* BtoCSTR(bstr)
*
* Convert (in place) a B string to a C string.
*/
void BtoCSTR(bstr)
char *bstr;
{
register int i;
register UBYTE *bptr, *cptr;
cptr=(UBYTE *)bstr; /* point to input B string */
bptr=cptr; /* output starts at B string len spot */
for(i=*bptr++; i!=0; i--) *cptr++=*bptr++; /* left shift the string */
*cptr='\0'; /* terminate it */
}
/*
* CtoBSTR(cstr)
*
* Convert (in place) a C string to a B string.
*/
void CtoBSTR(cstr)
char *cstr;
{
register int i, len;
register UBYTE *cptr, *bptr;
cptr=(UBYTE *)cstr; /* pointer to input */
for(i=0; *cptr; i++, cptr++); /* count & push pointer to input */
len=i; /* save count */
bptr=cptr; /* point at end of input */
cptr--; /* back up over null */
while(i--) *bptr--=*cptr--; /* right the string */
*bptr=(UBYTE)len; /* stuff in the string length */
}